From b6805cb12b95f04ba8d51dcc365106965937d207 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Tue, 30 Aug 2005 12:33:55 +0000 Subject: [PATCH] re-registration (instrumentation, and fish optimization) --- ChangeLog | 30 +++++++ babl/babl-classes.h | 4 + babl/babl-component.c | 15 ++-- babl/babl-conversion.c | 21 +++-- babl/babl-extension.c | 26 +++--- babl/babl-fish.c | 192 ++++++++++++++++++++++++----------------- babl/babl-format.c | 17 +--- babl/babl-model.c | 15 ++-- babl/babl-type.c | 15 ++-- 9 files changed, 195 insertions(+), 140 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8836549..149dfff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2005-08-30 Øyvind Kolås + + * babl/babl-classes.h: Added instrumentation variables to + BablConversion and BablFish. + * babl/babl-conversion.c: + (babl_conversion_new): Handle re-registration. + (conversion_new), + (babl_conversion_process): instrumentation variables + * babl/babl-component.c: + (babl_component_new): Handle re-registration. + * babl/babl-extension.c: Code cleanup. + (babl_extension_base): Handle re-registration. + (babl_extension_load_dir): close dir handle when done. + * babl/babl-fish.c: + (create_name) + (babl_fish_new): instrumentation variables, autogenerated + name. + (babl_fish_reference_new): instrumentation variables, + autogenerated name. + (babl_process): instrumentation variables. + (babl_conversion_find): use the lists of the source type for + the search (speed improvement). + (babl_fish): + (process_same_model): reference process with fewer steps. + (babl_fish_reference_process): use fast path when models are + the same. + * babl/babl-format.c: (babl_format_new): Handle re-registration. + * babl/babl-model.c: (babl_model_new): handle re-registration. + * babl/babl-type.c: (babl_type_new): handle re-registration. + 2005-08-30 Øyvind Kolås * babl/babl-memory.c: (babl_free): freeing of non babl allocated diff --git a/babl/babl-classes.h b/babl/babl-classes.h index 1ee34db..f6850b4 100644 --- a/babl/babl-classes.h +++ b/babl/babl-classes.h @@ -106,6 +106,8 @@ BablConversion { BablFuncPlanar planar; BablFuncPlanarBit planar_bit; } function; + int processings; + long pixels; } BablConversion; typedef struct { @@ -226,6 +228,8 @@ typedef struct BablInstance instance; union Babl *source; union Babl *destination; + int processings; + long pixels; } BablFish; /* BablFishReference on the double versions of conversions diff --git a/babl/babl-component.c b/babl/babl-component.c index e5f758b..c0f7604 100644 --- a/babl/babl-component.c +++ b/babl/babl-component.c @@ -116,15 +116,12 @@ babl_component_new (const char *name, babl = component_new (name, id, luma, chroma, alpha); - if (db_insert (babl) == babl) - { - return babl; - } - else - { - each_babl_component_destroy (babl, NULL); - return NULL; - } + { + Babl *ret = db_insert (babl); + if (ret!=babl) + babl_free (babl); + return ret; + } } BABL_CLASS_TEMPLATE (babl_component) diff --git a/babl/babl-conversion.c b/babl/babl-conversion.c index 76bc79c..d400ca3 100644 --- a/babl/babl-conversion.c +++ b/babl/babl-conversion.c @@ -118,6 +118,9 @@ conversion_new (const char *name, babl->conversion.time_cost = time_cost; babl->conversion.loss = loss; + babl->conversion.pixels = 0; + babl->conversion.processings = 0; + babl_add_ptr_to_list ((void ***)&(source->type.from), babl); babl_add_ptr_to_list ((void ***)&(destination->type.to), babl); @@ -227,15 +230,12 @@ babl_conversion_new (Babl *source, babl = conversion_new (create_name (source, destination), id, source, destination, time_cost, loss, linear, planar, planar_bit); - if (db_insert (babl) == babl) - { - return babl; - } - else - { - each_babl_conversion_destroy (babl, NULL); - return NULL; - } + { + Babl *ret = db_insert (babl); + if (ret!=babl) + babl_free (babl); + return ret; + } } static void @@ -285,6 +285,9 @@ babl_conversion_process (BablConversion *conversion, /*TODO: build planar formats if needed when linear pointers are passed in */ assert (BABL_IS_BABL (conversion)); + conversion->processings++; + conversion->pixels += n; + switch (BABL(conversion)->class_type) { case BABL_CONVERSION_TYPE: diff --git a/babl/babl-extension.c b/babl/babl-extension.c index 6c9573a..6954eb9 100644 --- a/babl/babl-extension.c +++ b/babl/babl-extension.c @@ -17,12 +17,12 @@ * Boston, MA 02111-1307, USA. */ +#define BABL_DYNAMIC_EXTENSIONS #define BABL_PATH "/usr/lib/babl:/usr/local/lib/babl:~/.babl"; #define BABL_PATH_SEPERATOR "/" #define BABL_LIST_SEPERATOR ':' -#define BABL_DYNAMIC_EXTENSIONS #define BABL_INIT_HOOK init_hook(); #define BABL_DESTROY_HOOK destroy_hook(); @@ -99,19 +99,17 @@ babl_extension_base (void) dl_handle, destroy); babl_set_extender (babl); - babl_base_init (); - if (db_insert (babl) == babl) - { - babl_set_extender (NULL); - return babl; - } - else - { - each_babl_extension_destroy (babl, NULL); - babl_set_extender (NULL); - return NULL; - } + { + Babl *ret = db_insert (babl); + if (ret!=babl) + babl_free (babl); + else + babl_base_init (); + babl = ret; + } + babl_set_extender (NULL); + return babl; } static void @@ -231,6 +229,7 @@ babl_extension_load_dir (const char *base_path) } } + closedir (dir); } } @@ -245,7 +244,6 @@ babl_dir_list (void) return ret; } - static char * expand_path (char *path) { diff --git a/babl/babl-fish.c b/babl/babl-fish.c index e33fd36..442bc7f 100644 --- a/babl/babl-fish.c +++ b/babl/babl-fish.c @@ -37,42 +37,50 @@ each_babl_fish_destroy (Babl *babl, return 0; /* continue iterating */ } -BablFish * +static char buf[1024]; +static char * +create_name (Babl *source, + Babl *destination, + int is_reference) +{ + /* fish names are intentionally kept short */ + snprintf (buf, 1024, "%s %p %p", + is_reference?"ref " + :"", + source, destination); + return buf; +} + +Babl * babl_fish_new (Babl *source, Babl *destination) { Babl *babl = NULL; + const char *name; assert (BABL_IS_BABL (source)); assert (BABL_IS_BABL (destination)); + + name = create_name (source, destination, 0); - babl = babl_calloc (sizeof (BablFish), 1); + babl = babl_malloc (sizeof (BablFishReference) + + strlen (name) + 1); babl->class_type = BABL_FISH; babl->instance.id = 0; - babl->instance.name = "Fishy"; + babl->instance.name = ((void *)babl) + sizeof(BablFishReference); + strcpy (babl->instance.name, name); babl->fish.source = (union Babl*)source; babl->fish.destination = (union Babl*)destination; - if (db_insert (babl) == babl) - { - return (BablFish*)babl; - } - else - { - each_babl_fish_destroy (babl, NULL); - return NULL; - } + babl->fish.processings = 0; + babl->fish.pixels = 0; -/* Might make sense to allow a precalculated shortcut to - * participate in later checks for optimal conversions, then we - * should also have better generated names,. model + datatype - * is a possibility , or even full single line serialization of - * components with types. - * - babl_add_ptr_to_list ((void ***)&(source->type.from), babl); - babl_add_ptr_to_list ((void ***)&(destination->type.to), babl); - */ - return (BablFish*)babl; + { + Babl *ret = db_insert (babl); + if (ret!=babl) + babl_free (babl); + return ret; + } } typedef struct SearchData @@ -82,44 +90,30 @@ typedef struct SearchData BablConversion *result; } SearchData; -static int -find_conversion (Babl *babl, - void *user_data) -{ - SearchData *sd = user_data; - - if (BABL(babl->conversion.source) == sd->source && - BABL(babl->conversion.destination) == sd->destination) - { - sd->result = (BablConversion*)babl; - return 1; - } - return 0; -} - BablConversion *babl_conversion_find (void *source, void *destination) { - SearchData data; - data.source = BABL(source); - data.destination = BABL(destination); - data.result = NULL; - babl_conversion_each (find_conversion, &data); + int i=0; + Babl **conversion; - if (!data.result) + conversion = (void*)BABL(source)->type.from; + while (conversion[i]) { - babl_fatal ("args=('%s', '%s'): failed, aborting", - data.source->instance.name, - data.destination->instance.name); + if (conversion[i]->conversion.destination == destination) + return (BablConversion*)conversion[i]; + i++; } - return data.result; + babl_fatal ("failed, aborting"); + return NULL; } + Babl * babl_fish_reference_new (Babl *source, Babl *destination) { Babl *babl = NULL; + char *name = create_name (source, destination, 1); assert (BABL_IS_BABL (source)); assert (BABL_IS_BABL (destination)); @@ -127,31 +121,31 @@ babl_fish_reference_new (Babl *source, assert (source->class_type == BABL_FORMAT); assert (destination->class_type == BABL_FORMAT); - babl = babl_calloc (sizeof (BablFishReference), 1); + babl = babl_malloc (sizeof (BablFishReference) + + strlen (name) + 1); babl->class_type = BABL_FISH_REFERENCE; babl->instance.id = 0; - babl->instance.name = NULL; + babl->instance.name = ((void *)babl) + sizeof(BablFishReference); + strcpy (babl->instance.name, name); babl->fish.source = (union Babl*)source; babl->fish.destination = (union Babl*)destination; - - if (db_insert (babl) == babl) - { - return babl; - } - else - { - each_babl_fish_destroy (babl, NULL); - return NULL; - } - return babl; + babl->fish.processings = 0; + babl->fish.pixels = 0; + + { + Babl *ret = db_insert (babl); + if (ret!=babl) + babl_free (babl); + return ret; + } } Babl * babl_fish (void *source, void *destination) { - Babl *source_format = NULL; + Babl *source_format = NULL; Babl *destination_format = NULL; assert (source); @@ -170,6 +164,7 @@ babl_fish (void *source, if (!source_format) { babl_log ("args=(%p, %p) source format invalid", source, destination); + return NULL; } if (BABL_IS_BABL (destination)) @@ -185,6 +180,7 @@ babl_fish (void *source, if (!destination_format) { babl_log ("args=(%p, %p) destination format invalid", source, destination); + return NULL; } return babl_fish_reference_new (source_format, destination_format); @@ -302,6 +298,45 @@ convert_from_double (BablFormat *destination_fmt, babl_free (dst_img); } + +static int +process_same_model (Babl *babl, + BablImage *source, + BablImage *destination, + long n) +{ + void *double_buf; + + if (BABL_IS_BABL (source) || + BABL_IS_BABL (destination)) + { + babl_log ("args=(%p, %p, %p, %li): trying to handle BablImage (unconfirmed code)", + babl_fish, source, destination, n); + } + + double_buf = babl_malloc(sizeof (double) * n * + BABL(babl->fish.source)->format.model->components); + + convert_to_double ( + (BablFormat*) BABL(babl->fish.source), + BABL_IS_BABL(source)?source:NULL, + BABL_IS_BABL(source)?NULL:source, + double_buf, + n + ); + + convert_from_double ( + (BablFormat*) BABL(babl->fish.destination), + double_buf, + BABL_IS_BABL(destination)?destination:NULL, + BABL_IS_BABL(destination)?NULL:destination, + n + ); + + babl_free (double_buf); + return 0; +} + static int babl_fish_reference_process (Babl *babl, BablImage *source, @@ -315,23 +350,10 @@ babl_fish_reference_process (Babl *babl, Babl *rgba_image; Babl *destination_image; - /* FIXME: assumptions made about memory requirements that - * are not good - */ - source_double_buf = babl_malloc(sizeof (double) * n * 4); - rgba_double_buf = babl_malloc(sizeof (double) * n * 4); - destination_double_buf = babl_malloc(sizeof (double) * n * 4); + if (BABL(babl->fish.source)->format.model == + BABL(babl->fish.destination)->format.model) + return process_same_model (babl, source, destination, n); - source_image = babl_image_from_linear ( - source_double_buf, - BABL(BABL((babl->fish.source)) -> format.model)); - rgba_image = babl_image_from_linear ( - rgba_double_buf, - babl_model_id (BABL_RGBA)); - destination_image = babl_image_from_linear ( - destination_double_buf, - BABL(BABL((babl->fish.destination))->format.model)); - if (BABL_IS_BABL (source) || BABL_IS_BABL (destination)) { @@ -339,6 +361,19 @@ babl_fish_reference_process (Babl *babl, babl_fish, source, destination, n); } + source_double_buf = babl_malloc(sizeof (double) * n * + BABL(babl->fish.source)->format.model->components); + rgba_double_buf = babl_malloc(sizeof (double) * n * 4); + destination_double_buf = babl_malloc(sizeof (double) * n * + BABL(babl->fish.destination)->format.model->components); + + source_image = babl_image_from_linear ( + source_double_buf,BABL(BABL((babl->fish.source)) -> format.model)); + rgba_image = babl_image_from_linear ( + rgba_double_buf, babl_model_id (BABL_RGBA)); + destination_image = babl_image_from_linear ( + destination_double_buf, BABL(BABL((babl->fish.destination))->format.model)); + convert_to_double ( (BablFormat*) BABL(babl->fish.source), BABL_IS_BABL(source)?source:NULL, @@ -404,6 +439,9 @@ babl_process (Babl *babl, assert (BABL_IS_BABL (babl)); assert (n>0); + babl->fish.processings++; + babl->fish.pixels += n; + if (babl->class_type == BABL_FISH) return babl_fish_process (babl, source, destination, n); diff --git a/babl/babl-format.c b/babl/babl-format.c index e63f78e..b00d5a2 100644 --- a/babl/babl-format.c +++ b/babl/babl-format.c @@ -252,20 +252,11 @@ babl_format_new (void *first_arg, component, sampling, type); { - Babl *ret; - ret = db_insert (babl); - - if (ret==babl) - { - return babl; - } - else - { - each_babl_format_destroy (babl, NULL); - return ret; - } + Babl *ret = db_insert (babl); + if (ret!=babl) + babl_free (babl); + return ret; } - } BABL_CLASS_TEMPLATE (babl_format) diff --git a/babl/babl-model.c b/babl/babl-model.c index 787f5b6..d42a8b1 100644 --- a/babl/babl-model.c +++ b/babl/babl-model.c @@ -160,15 +160,12 @@ babl_model_new (void *first_argument, babl = model_new (create_name (name, components, component), id, components, component); - if (db_insert (babl) == babl) - { - return babl; - } - else - { - each_babl_model_destroy (babl, NULL); - return NULL; - } + { + Babl *ret = db_insert (babl); + if (ret!=babl) + babl_free (babl); + return ret; + } } BABL_CLASS_TEMPLATE (babl_model) diff --git a/babl/babl-type.c b/babl/babl-type.c index fbdb9c3..6ea73a4 100644 --- a/babl/babl-type.c +++ b/babl/babl-type.c @@ -133,15 +133,12 @@ babl_type_new (const char *name, babl = type_new (name, id, bits); - if (db_insert (babl) == babl) - { - return babl; - } - else - { - each_babl_type_destroy (babl, NULL); - return NULL; - } + { + Babl *ret = db_insert (babl); + if (ret!=babl) + babl_free (babl); + return ret; + } } BABL_CLASS_TEMPLATE (babl_type) -- 2.30.2